﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Web.Routing;

namespace Web.UI.TypeExtensions
{
    public static class TypeExtensions
    {
        public static string GetEnumDescription(this Enum value)
        {
            var fi = value.GetType().GetField(value.ToString());
            var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
                typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : value.ToString();
        }

        public static IDictionary<string, object> ToDictionary(this object data)
        {
            if (data == null)
            {
                return new Dictionary<string, object>();
            }
            if (data.GetType().IsIDictionary())
            {
                return (IDictionary<string, object>)data;
            }
            return HtmlHelper.AnonymousObjectToHtmlAttributes(data);
        }

        public static bool IsIDictionary(this Type t)
        {
            return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>)) || t.Name == "RouteValueDictionary";
        }

        public static IDictionary<string, object> ToHtmlDataAttributes(this object data)
        {
            if (data == null)
            {
                return new Dictionary<string, object>();
            }
            var dictionary = data.ToDictionary();
            var routeValueDictionary = new RouteValueDictionary();
            foreach (var current in dictionary)
            {
                routeValueDictionary.Add("data-" + current.Key, current.Value);
            }
            return routeValueDictionary;
        }

        public static IDictionary<string, object> AddOrMergeAttribute(this IDictionary<string, object> data, string key, string value)
        {
            if (data.ContainsKey(key))
            {
                if (data[key] is string && !Regex.IsMatch(data[key].ToString(), string.Format("(^|\\s){0}($|\\s)", value)))
                {
                    data[key] = data[key] + " " + value;
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(value))
                {
                    data.Add(key, value);
                }
            }
            return data;
        }

        public static IDictionary<string, object> AddOrMergeCssClass(this IDictionary<string, object> data, string attrValue)
        {
            return AddOrMergeAttribute(data, "class", attrValue);
        }

        public static IDictionary<string, object> AddOrReplace(this IDictionary<string, object> data, string key, string value)
        {
            if (data.ContainsKey(key))
            {
                data[key] = value;
            }
            else
            {
                data.Add(key, value);
            }
            return data;
        }

        public static IDictionary<string, object> FormatHtmlAttributes(this IDictionary<string, object> htmlAttributes)
        {
            if (htmlAttributes == null)
            {
                return new Dictionary<string, object>();
            }
            IDictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (var current in htmlAttributes.Keys)
            {
                dictionary.Add(current.Replace('_', '-'), htmlAttributes[current]);
            }
            return dictionary;
        }

        public static void MergeHtmlAttributes(this IDictionary<string, object> source, IDictionary<string, object> htmlAttributes)
        {
            if (htmlAttributes == null)
            {
                return;
            }
            foreach (var current in htmlAttributes)
            {
                if (!source.ContainsKey(current.Key))
                {
                    source.Add(current.Key, current.Value);
                }
                else
                {
                    if (current.Key.ToLower() == "class")
                    {
                        source[current.Key] += " " + current.Value;
                    }
                    else
                    {
                        source[current.Key] = current.Value;
                    }
                }
            }
        }

        public static string TrimEnd(this string source, string trimString)
        {
            return Regex.Replace(source, string.Format("{0}$", trimString), String.Empty);
        }
    }
}